namespace SimpleWebServices.Data
{
    using System;
    using System.Data.SqlClient;
    using System.Data.SqlTypes;
    using System.IO;
    using System.Xml;
    using System.Xml.XPath;
    using Xunit;

    public sealed class SqlParameterCollectionExtensionMethodsFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(typeof(SqlParameterCollectionExtensionMethods).IsStatic());
        }

        [Fact]
        public void op_AddChar_SqlParameterCollection_string_string_int()
        {
            string expected = "value";
            string actual = null;

            using (SqlCommand command = new SqlCommand())
            {
                command.Parameters.AddChar("name", expected, 123);

                actual = (string)command.Parameters["name"].Value;
            }

            Assert.Equal<string>(expected, actual);
        }

        [Fact]
        public void op_AddChar_SqlParameterCollection_string_stringEmpty_int()
        {
            string expected = string.Empty;
            string actual = null;

            using (SqlCommand command = new SqlCommand())
            {
                command.Parameters.AddChar("name", expected, 123);

                actual = (string)command.Parameters["name"].Value;
            }

            Assert.Equal<string>(expected, actual);
        }

        [Fact]
        public void op_AddChar_SqlParameterCollection_string_stringNull_int()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentNullException>(() => command.Parameters.AddChar("name", null, 123));
            }
        }

        [Fact]
        public void op_AddChar_SqlParameterCollection_stringEmpty_string_int()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentOutOfRangeException>(() => command.Parameters.AddChar(string.Empty, "value", 123));
            }
        }

        [Fact]
        public void op_AddChar_SqlParameterCollection_stringNull_string_int()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentNullException>(() => command.Parameters.AddChar(null, "value", 123));
            }
        }

        [Fact]
        public void op_AddDateTime_SqlParameterCollection_string_DateTime()
        {
            DateTime expected = DateTime.UtcNow;
            DateTime actual = DateTime.MinValue;

            using (SqlCommand command = new SqlCommand())
            {
                command.Parameters.AddDateTime("name", expected);

                actual = (DateTime)command.Parameters["name"].Value;
            }

            Assert.Equal<DateTime>(expected, actual);
        }

        [Fact]
        public void op_AddDateTime_SqlParameterCollection_stringEmpty_DateTime()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentOutOfRangeException>(() => command.Parameters.AddDateTime(string.Empty, DateTime.Today));
            }
        }

        [Fact]
        public void op_AddDateTime_SqlParameterCollection_stringNull_DateTime()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentNullException>(() => command.Parameters.AddDateTime(null, DateTime.Today));
            }
        }

        [Fact]
        public void op_AddInt32_SqlParameterCollection_string_int()
        {
            int expected = 123;
            int actual = 0;

            using (SqlCommand command = new SqlCommand())
            {
                command.Parameters.AddInt32("name", expected);

                actual = (int)command.Parameters["name"].Value;
            }

            Assert.Equal<int>(expected, actual);
        }

        [Fact]
        public void op_AddInt32_SqlParameterCollection_stringEmpty_DateTime()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentOutOfRangeException>(() => command.Parameters.AddInt32(string.Empty, 123));
            }
        }

        [Fact]
        public void op_AddInt32_SqlParameterCollection_stringNull_DateTime()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentNullException>(() => command.Parameters.AddInt32(null, 123));
            }
        }

        [Fact]
        public void op_AddNVarChar_SqlParameterCollection_string_string_int()
        {
            string expected = "value";
            string actual = null;

            using (SqlCommand command = new SqlCommand())
            {
                command.Parameters.AddNVarChar("name", expected, 123);

                actual = (string)command.Parameters["name"].Value;
            }

            Assert.Equal<string>(expected, actual);
        }

        [Fact]
        public void op_AddNVarChar_SqlParameterCollection_string_stringEmpty_int()
        {
            string expected = string.Empty;
            string actual = null;

            using (SqlCommand command = new SqlCommand())
            {
                command.Parameters.AddNVarChar("name", expected, 123);

                actual = (string)command.Parameters["name"].Value;
            }

            Assert.Equal<string>(expected, actual);
        }

        [Fact]
        public void op_AddNVarChar_SqlParameterCollection_string_stringNull_int()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentNullException>(() => command.Parameters.AddNVarChar("name", null, 123));
            }
        }

        [Fact]
        public void op_AddNVarChar_SqlParameterCollection_stringEmpty_string_int()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentOutOfRangeException>(() => command.Parameters.AddNVarChar(string.Empty, "value", 123));
            }
        }

        [Fact]
        public void op_AddNVarChar_SqlParameterCollection_stringNull_string_int()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentNullException>(() => command.Parameters.AddNVarChar(null, "value", 123));
            }
        }

        [Fact]
        public void op_AddToken_SqlParameterCollection_string_Guid()
        {
            Guid expected = Guid.NewGuid();
            Guid actual = Guid.Empty;

            using (SqlCommand command = new SqlCommand())
            {
                command.Parameters.AddToken("name", expected);

                actual = (Guid)command.Parameters["name"].Value;
            }

            Assert.Equal<Guid>(expected, actual);
        }

        [Fact]
        public void op_AddToken_SqlParameterCollection_stringEmpty_Guid()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentOutOfRangeException>(() => command.Parameters.AddToken(string.Empty, Guid.NewGuid()));
            }
        }

        [Fact]
        public void op_AddToken_SqlParameterCollection_stringNull_Guid()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentNullException>(() => command.Parameters.AddToken(null, Guid.NewGuid()));
            }
        }

        [Fact]
        public void op_AddVarChar_SqlParameterCollection_string_string_int()
        {
            string expected = "value";
            string actual = null;

            using (SqlCommand command = new SqlCommand())
            {
                command.Parameters.AddVarChar("name", expected, 123);

                actual = (string)command.Parameters["name"].Value;
            }

            Assert.Equal<string>(expected, actual);
        }

        [Fact]
        public void op_AddVarChar_SqlParameterCollection_string_stringEmpty_int()
        {
            string expected = string.Empty;
            string actual = null;

            using (SqlCommand command = new SqlCommand())
            {
                command.Parameters.AddVarChar("name", expected, 123);

                actual = (string)command.Parameters["name"].Value;
            }

            Assert.Equal<string>(expected, actual);
        }

        [Fact]
        public void op_AddVarChar_SqlParameterCollection_string_stringNull_int()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentNullException>(() => command.Parameters.AddVarChar("name", null, 123));
            }
        }

        [Fact]
        public void op_AddVarChar_SqlParameterCollection_stringEmpty_string_int()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentOutOfRangeException>(() => command.Parameters.AddVarChar(string.Empty, "value", 123));
            }
        }

        [Fact]
        public void op_AddVarChar_SqlParameterCollection_stringNull_string_int()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentNullException>(() => command.Parameters.AddVarChar(null, "value", 123));
            }
        }

        [Fact]
        public void op_AddXml_SqlParameterCollection_string_IXPathNavigable()
        {
            XmlDocument expected = new XmlDocument();
            expected.LoadXml("<root/>");

            using (SqlCommand command = new SqlCommand())
            {
                command.Parameters.AddXml("name", expected);

                Assert.IsType<SqlXml>(command.Parameters["name"].Value);
            }
        }

        [Fact]
        public void op_AddXml_SqlParameterCollection_stringEmpty_IXPathNavigable()
        {
            XmlDocument expected = new XmlDocument();
            expected.LoadXml("<root/>");

            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentOutOfRangeException>(() => command.Parameters.AddXml(string.Empty, expected));
            }
        }

        [Fact]
        public void op_AddXml_SqlParameterCollection_stringNull_IXPathNavigable()
        {
            XmlDocument expected = new XmlDocument();
            expected.LoadXml("<root/>");

            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentNullException>(() => command.Parameters.AddXml(null, expected));
            }
        }

        [Fact]
        public void op_AddXml_SqlParameterCollection_string_IXPathNavigableNull()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentNullException>(() => command.Parameters.AddXml("name", null as IXPathNavigable));
            }
        }

        [Fact]
        public void op_AddXml_SqlParameterCollection_string_XmlReader()
        {
            using (SqlCommand command = new SqlCommand())
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    using (StreamWriter writer = new StreamWriter(stream))
                    {
                        writer.Write("<root/>");
                        writer.Flush();

                        stream.Position = 0;

                        using (XmlReader reader = new XmlTextReader(stream))
                        {
                            command.Parameters.AddXml("name", reader);
                        }
                    }
                }

                Assert.IsType<SqlXml>(command.Parameters["name"].Value);
            }
        }

        [Fact]
        public void op_AddXml_SqlParameterCollection_stringEmpty_XmlReader()
        {
            using (SqlCommand command = new SqlCommand())
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    using (StreamWriter writer = new StreamWriter(stream))
                    {
                        writer.Write("<root/>");
                        writer.Flush();

                        stream.Position = 0;

                        using (XmlReader reader = new XmlTextReader(stream))
                        {
                            Assert.Throws<ArgumentOutOfRangeException>(() => command.Parameters.AddXml(string.Empty, reader));
                        }
                    }
                }
            }
        }

        [Fact]
        public void op_AddXml_SqlParameterCollection_stringNull_XmlReader()
        {
            using (SqlCommand command = new SqlCommand())
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    using (StreamWriter writer = new StreamWriter(stream))
                    {
                        writer.Write("<root/>");
                        writer.Flush();

                        stream.Position = 0;

                        using (XmlReader reader = new XmlTextReader(stream))
                        {
                            Assert.Throws<ArgumentNullException>(() => command.Parameters.AddXml(null, reader));
                        }
                    }
                }
            }
        }

        [Fact]
        public void op_AddXml_SqlParameterCollection_string_XmlReaderNull()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentNullException>(() => command.Parameters.AddXml("name", null as XmlReader));
            }
        }

        [Fact]
        public void op_AddXml_SqlParameterCollection_string_SqlXml()
        {
            using (SqlCommand command = new SqlCommand())
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    using (StreamWriter writer = new StreamWriter(stream))
                    {
                        writer.Write("<root/>");
                        writer.Flush();

                        stream.Position = 0;

                        using (XmlReader reader = new XmlTextReader(stream))
                        {
                            command.Parameters.AddXml("name", new SqlXml(reader));
                        }
                    }
                }

                Assert.IsType<SqlXml>(command.Parameters["name"].Value);
            }
        }

        [Fact]
        public void op_AddXml_SqlParameterCollection_stringEmpty_SqlXml()
        {
            using (SqlCommand command = new SqlCommand())
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    using (StreamWriter writer = new StreamWriter(stream))
                    {
                        writer.Write("<root/>");
                        writer.Flush();

                        stream.Position = 0;

                        using (XmlReader reader = new XmlTextReader(stream))
                        {
                            Assert.Throws<ArgumentOutOfRangeException>(() => command.Parameters.AddXml(string.Empty, new SqlXml(reader)));
                        }
                    }
                }
            }
        }

        [Fact]
        public void op_AddXml_SqlParameterCollection_stringNull_SqlXml()
        {
            using (SqlCommand command = new SqlCommand())
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    using (StreamWriter writer = new StreamWriter(stream))
                    {
                        writer.Write("<root/>");
                        writer.Flush();

                        stream.Position = 0;

                        using (XmlReader reader = new XmlTextReader(stream))
                        {
                            Assert.Throws<ArgumentNullException>(() => command.Parameters.AddXml(null, new SqlXml(reader)));
                        }
                    }
                }
            }
        }

        [Fact]
        public void op_AddXml_SqlParameterCollection_string_SqlXmlNull()
        {
            using (SqlCommand command = new SqlCommand())
            {
                Assert.Throws<ArgumentNullException>(() => command.Parameters.AddXml("name", null as SqlXml));
            }
        }
    }
}